﻿using EquipmentManager.Entities;
using EquipmentManager.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace EquipmentManager.BOLogic
{
    public class EquipmentBO : BOBase
    {
        public List<EquipmentBase> GetEquipments(long PostOfficeId)
        {
            try
            {
                var equipments = db.Set<EquipmentBase>().Where(e => e.PostOffice.Id == PostOfficeId && 
                    e.Status == EntityStatus.Active).OrderByDescending(e => e.CreatedDate).ToList();
                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> SearchEquipments(string searchModel)
        {
            List<EquipmentBase> equipments;
            try
            {
                if (searchModel == String.Empty)
                {
                    equipments = db.Set<EquipmentBase>().Where(e => e.Status == EntityStatus.Active).OrderBy(e => e.CreatedDate).ToList();
                }
                else
                {
                    equipments = db.Set<EquipmentBase>().Where(e => (e.Name.Contains(searchModel) ||
                        e.Description.Contains(searchModel) || e.Number.Contains(searchModel) || e.Note.Contains(searchModel) ||
                        e.SerialNumber.Contains(searchModel) || e.WorkPlace.Contains(searchModel))
                        && e.Status == EntityStatus.Active).OrderByDescending(e => e.CreatedDate).ToList();
                }

                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> SearchEquipmentsOper(string searchModel)
        {
            List<EquipmentBase> equipments;
            try
            {
                if (searchModel == String.Empty)
                {
                    equipments = db.Set<EquipmentBase>().Where(e => e.PostOffice.Region.Id == User.Region.Id && 
                        e.Status == EntityStatus.Active).OrderBy(e => e.CreatedDate).ToList();
                }
                else
                {
                    equipments = db.Set<EquipmentBase>().Where(e => (e.Name.Contains(searchModel) ||
                        e.Description.Contains(searchModel) || e.Number.Contains(searchModel) || e.Note.Contains(searchModel) ||
                        e.SerialNumber.Contains(searchModel) || e.WorkPlace.Contains(searchModel))
                        && e.PostOffice.Region.Id == User.Region.Id && e.Status == EntityStatus.Active).OrderByDescending(e => e.CreatedDate).ToList();
                }

                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> GetAllEquipments()
        {
            try
            {
                var equipments = db.Set<EquipmentBase>().Where(e => e.Status == EntityStatus.Active).OrderByDescending(e => e.CreatedDate).ToList();
                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> GetAllRecentEquipments()
        {
            try
            {
                DateTime weekAgo = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0));

                var equipments = db.Set<EquipmentBase>().Where(e => e.Status == EntityStatus.Active &&
                    e.CreatedDate >= weekAgo).OrderByDescending(e => e.CreatedDate).ToList();
                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> GetOperEquipments()
        {
            try
            {
                var equipments = db.Set<EquipmentBase>().Where(e => e.PostOffice.Region.Id == User.Region.Id &&
                    e.Status == EntityStatus.Active).OrderByDescending(e => e.CreatedDate).ToList();
                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public List<EquipmentBase> GetAllRecentOperEquipments()
        {
            try
            {
                DateTime weekAgo = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0));

                var equipments = db.Set<EquipmentBase>().Where(e => e.PostOffice.Region.Id == User.Region.Id &&
                    e.Status == EntityStatus.Active && e.CreatedDate >= weekAgo).OrderByDescending(e => e.CreatedDate).ToList();
                return equipments;
            }
            catch (Exception ex)
            {
                return new List<EquipmentBase>();
            }
        }

        public EquipmentBase GetEquipment(long EquipmentId)
        {
            try
            {
                var equipment = db.Set<EquipmentBase>().Single(e => e.Id == EquipmentId);

                return equipment;
            }
            catch (Exception ex)
            {
                return new EquipmentBase();
            }
        }

        public bool IsNumberUnique(CreateModel<EquipmentBase> model)
        {
            var isExist = db.Set<EquipmentBase>().Where(e => e.Number == model.Instance.Number && e.Status == EntityStatus.Active).ToList();

            if (isExist.Count == 0)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool CreateNewEquipment(CreateModel<EquipmentBase> model)
        {
            try
            {
                var admin = db.Set<User>().Single(c => c.Id == User.Id);

                if (admin.Role == UserRole.Admin || admin.Role == UserRole.Operator)
                {
                    if (model.Instance.Name == null || model.Instance.Number == null
                        || model.Instance.SerialNumber == null || model.Instance.WorkPlace == null
                        || model.Instance.Year == null)
                    {
                        return false;
                    }
                    
                    model.Instance.Status = EntityStatus.Active;
                    model.Instance.PostOffice = db.Set<PostOffice>().Single(p => p.Id == model.ParentId);
                    model.Instance.CreatedDate = DateTime.Now;

                    db.Set<EquipmentBase>().Add(model.Instance);
                    db.SaveChanges();
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public bool EditEquipment(CreateModel<EquipmentBase> model)
        {
            try
            {
                var equipment = db.Set<EquipmentBase>().Single(c => c.Id == model.Instance.Id);
                var admin = db.Set<User>().Single(c => c.Id == User.Id);

                if (admin.Role == UserRole.Admin || admin.Role == UserRole.Operator)
                {
                    // можно создавать новую измененную, а эту делать неактивной если что;)
                    equipment.Number = model.Instance.Number;
                    equipment.SerialNumber = model.Instance.SerialNumber;
                    equipment.Name = model.Instance.Name;
                    equipment.Description = model.Instance.Description;
                    equipment.Year = model.Instance.Year;
                    equipment.WorkPlace = model.Instance.WorkPlace;
                    equipment.State = model.Instance.State;
                    equipment.Note = model.Instance.Note;
                    db.SaveChanges();
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public bool DeleteEquipment(long EquipmentId)
        {
            try
            {
                var equipment = db.Set<EquipmentBase>().Single(c => c.Id == EquipmentId);
                var admin = db.Set<User>().Single(c => c.Id == User.Id);

                if (admin.Role == UserRole.Admin || admin.Role == UserRole.Operator)
                {
                    equipment.Status = EntityStatus.Deleted;
                    db.SaveChanges();
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}